Skip to content

fix: preserve tools with dependency property-name maps - #1428

Merged
DaleSeo merged 2 commits into
modelcontextprotocol:mainfrom
aphonpra-oai:codex/preserve-dependent-required-tools
Nov 11, 2026
Merged

DaleSeo merged 2 commits into
modelcontextprotocol:mainfrom
aphonpra-oai:codex/preserve-dependent-required-tools

Conversation

@aphonpra-oai

@aphonpra-oai aphonpra-oai commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

In a negotiated 2026-07-28 Streamable HTTP session, the client can remove a valid tool when its input schema has a property named x-mcp-header in dependentRequired or the legacy Draft 7 dependencies map. The annotation walker mistakes the property name for an off-chain header annotation, causing cache_tools_from_response to remove the tool from tools/list.

Handle the two keywords according to their contents:

  • Skip dependentRequired during annotation traversal: it contains property names and arrays of names, not schemas.
  • Walk the values of dependencies, ignoring the property names used as keys. Values can be name arrays or actual schemas; real schemas must still be checked for misplaced header annotations. This also prevents a dependency named default from concealing an invalid annotation.

For example, this schema is valid with either dependency keyword:

{
  "type": "object",
  "properties": {
    "x-mcp-header": { "type": "string" },
    "tenant": { "type": "string", "x-mcp-header": "Tenant" }
  },
  "dependentRequired": { "x-mcp-header": ["tenant"] }
}

Regression coverage verifies that name-array, schema, and boolean dependency values do not turn property names into annotations; valid tools remain in the returned list and cache; and actual off-chain annotations remain rejected, including inside dependency schemas named default, properties, or x-mcp-header.

References: JSON Schema 2020-12: dependentRequired, Draft 7: dependencies.

Local validation

The three new or expanded legacy-dependency regressions fail on the previous PR head 00f9202. With the legacy keyword handled as a map, all 59 header tests and 4 tool-list/cache tests pass.

Commands (one build job and one test thread):

cargo test -p rmcp --lib --features client,transport-streamable-http-client,transport-streamable-http-server transport::common::mcp_headers -- --test-threads=1
cargo test -p rmcp --lib --features client,transport-streamable-http-client,transport-streamable-http-server cache_tools_ -- --test-threads=1

The full workspace suite was not run locally.

@github-actions github-actions Bot added T-core Core library changes T-transport Transport layer changes labels Nov 3, 2026
@github-actions
github-actions Bot requested a review from jamadeo November 3, 2026 07:05
@github-actions

github-actions Bot commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

@jamadeo is on triage rotation this week and is the reviewer for this one.

Labels come from the PR labeler. Please review the change.

Automated triage. Labels are a first pass and the assigned maintainer has the final say.

@aphonpra-oai
aphonpra-oai marked this pull request as ready for review November 3, 2026 23:02
@aphonpra-oai
aphonpra-oai requested a review from a team as a code owner November 3, 2026 23:02
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 3, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-09T22:35:27.330909Z 79df442 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@aphonpra-oai

Copy link
Copy Markdown
Contributor Author

Hey @DaleSeo

You reviewed our reconnect fix in #1363. While testing the Codex upgrade to 3.8.0, I found another issue where dependentRequired causes valid tools to get filtered out.

Could you take a look at #1428? It’s a small fix which stops the SDK from mistaking input names for header instructions and hiding valid tools. Tested discovery and successful tool calls locally through Codex.

@DaleSeo DaleSeo left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for tracking this down, @aphonpra-oai!

@aphonpra-oai aphonpra-oai changed the title fix: preserve tools with dependentRequired property-name maps fix: preserve tools with dependency property-name maps Nov 9, 2026
@aphonpra-oai
aphonpra-oai requested a review from DaleSeo November 10, 2026 01:25

@tsarlandie-oai tsarlandie-oai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified that @DaleSeo comments have been addressed and reviewed the code. LGTM!

@DaleSeo
DaleSeo merged commit f852ec0 into modelcontextprotocol:main Nov 11, 2026
24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

T-core Core library changes T-transport Transport layer changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants